package com.brsanthu.sgwidgets.client;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.smartgwt.client.data.Record;
import com.smartgwt.client.types.Alignment;
import com.smartgwt.client.types.SelectionStyle;
import com.smartgwt.client.types.VerticalAlignment;
import com.smartgwt.client.widgets.Canvas;
import com.smartgwt.client.widgets.ImgButton;
import com.smartgwt.client.widgets.events.ClickEvent;
import com.smartgwt.client.widgets.events.ClickHandler;
import com.smartgwt.client.widgets.events.DoubleClickEvent;
import com.smartgwt.client.widgets.events.DoubleClickHandler;
import com.smartgwt.client.widgets.grid.ListGrid;
import com.smartgwt.client.widgets.grid.ListGridField;
import com.smartgwt.client.widgets.grid.ListGridRecord;
import com.smartgwt.client.widgets.layout.HLayout;
import com.smartgwt.client.widgets.layout.VLayout;

import static com.brsanthu.sgwidgets.client.ClientUtils.*;

@SuppressWarnings("synthetic-access")
public class DualPaneList extends Canvas {

    private ListGrid leftList;
    private ListGrid rightList;
    private final boolean showBorder;
    private final String title;
    private final String width;
    private final String height;
    private LabelProvider labelProvider = null;
    
    public DualPaneList() {
        this("", false);
    }
    public DualPaneList(String title, boolean showBorder, String width, String height) {
        this.title = title;
        this.showBorder = showBorder;
        this.width = width;
        this.height = height;
        setTitle("<b>" + title + "</b>");
        setShowEdges(false);
        createCanvas();
    }

    public DualPaneList(String title, boolean showBorder) {
        this(title, showBorder, "100%", "100%");
    }
    
    public LabelProvider getLabelProvider() {
        return labelProvider;
    }
    public void setLabelProvider(LabelProvider labelProvider) {
        this.labelProvider = labelProvider;
    }

    private void createCanvas() {

        HLayout hlayout = new HLayout();
        hlayout.setMembersMargin(10);
        hlayout.setWidth(width);
        hlayout.setHeight(height);

        leftList = createListGrid();
        leftList.setEmptyMessage("All items are selected");
        leftList.setCanGroupBy(false);
        leftList.setCanPickFields(false);
        leftList.setCanReorderFields(false);
        leftList.setCanResizeFields(false);
        ListGridField field = new ListGridField("name", ClientUtils.bold("Available"));
        field.setWidth("100%");
        leftList.setFields(field);
        leftList.setWidth("50%");
        leftList.setHeight100();
        leftList.setSelectionType(SelectionStyle.MULTIPLE);
        leftList.setCanDragSelect(true);
        leftList.setShowAllRecords(true);
        leftList.setCanDragRecordsOut(true);
        leftList.setCanDrop(true);
        leftList.setCanEdit(false);
        leftList.addDoubleClickHandler(new DoubleClickHandler() {
            @Override
            public void onDoubleClick(DoubleClickEvent event) {
                moveRight();
            }
        });

        hlayout.addMember(leftList);

        VLayout vLayout = new VLayout();
        vLayout.setHeight100();
        vLayout.setAlign(VerticalAlignment.CENTER);
        vLayout.setAlign(Alignment.CENTER);
        vLayout.setWidth(16);

        ImgButton imgBtn = createImgButton("last.png");
        imgBtn.addClickHandler(new ClickHandler() {
            @Override
            public void onClick(ClickEvent event) {
                for (Record record : leftList.getRecords()) {
                    rightList.addData(record);
                }
                removeRecords(leftList);
            }
        });

        vLayout.addMember(imgBtn);

        imgBtn = createImgButton("next.png");
        imgBtn.addClickHandler(new ClickHandler() {
            @Override
            public void onClick(ClickEvent event) {
                moveRight();
            }
        });
        vLayout.addMember(imgBtn);

        imgBtn = createImgButton("previous.png");
        imgBtn.addClickHandler(new ClickHandler() {
            @Override
            public void onClick(ClickEvent event) {
                moveLeft();
            }
        });
        vLayout.addMember(imgBtn);

        imgBtn = createImgButton("first.png");
        imgBtn.addClickHandler(new ClickHandler() {
            @Override
            public void onClick(ClickEvent event) {
                for (Record record : rightList.getRecords()) {
                    leftList.addData(record);
                }
                removeRecords(rightList);
            }
        });
        vLayout.addMember(imgBtn);

        hlayout.addMember(vLayout);

        rightList = createListGrid();
        rightList.setEmptyMessage("No items are selected");
        rightList.setCanGroupBy(false);
        rightList.setCanPickFields(false);
        rightList.setCanReorderFields(false);
        rightList.setCanResizeFields(false);
        rightList.setWidth("50%");
        rightList.setHeight100();
        rightList.setSelectionType(SelectionStyle.MULTIPLE);
        rightList.setCanDragSelect(true);
        rightList.setShowAllRecords(true);
        field = new ListGridField("name", ClientUtils.bold("Selected"));
        field.setWidth("100%");
        rightList.setFields(field);
        rightList.setCanDragRecordsOut(true);
        rightList.setCanDrop(true);
        rightList.setCanEdit(false);
        rightList.addDoubleClickHandler(new DoubleClickHandler() {

            @Override
            public void onDoubleClick(DoubleClickEvent event) {
                moveLeft();
            }
        });

        hlayout.addMember(rightList);

        if (showBorder) {
            addChild(createSection(title, width, height, hlayout));
        } else {
            addChild(hlayout);
        }
    }

    private void moveRight() {
        for (Record record : leftList.getSelection()) {
            rightList.addData(record);
        }
        removeSelectedRecords(leftList);
    }

    private void moveLeft() {
        for (Record record : rightList.getSelection()) {
            leftList.addData(record);
        }
        removeSelectedRecords(rightList);
    }

    public void setData(List availableItems, List selectedItems) {

        removeRecords(leftList);
        removeRecords(rightList);

        if (selectedItems == null) {
            selectedItems = new ArrayList();
        }

        if (availableItems == null) {
            availableItems = new ArrayList();
        }

        Map<String, String> selectedItemsMap = new HashMap<String, String>();

        for (Object item : selectedItems) {
            ListGridRecord record = new ListGridRecord();
            record.setAttribute("name", getText(item));
            record.setAttribute("object", item);
            rightList.addData(record);
            selectedItemsMap.put(getText(item), "");
        }

        for (Object item : availableItems) {
            if (selectedItemsMap.get(getText(item)) == null) {
                ListGridRecord record = new ListGridRecord();
                record.setAttribute("name", getText(item));
                record.setAttribute("object", item);
                leftList.addData(record);
            }
        }
    }

    public List getSelectedItems() {
        List items = new ArrayList();
        ListGridRecord[] records = rightList.getRecords();
        for (ListGridRecord record : records) {
            items.add(record.getAttributeAsObject("object"));
        }

        return items;
    }
    
    public void reset() {
        setData(null, null);
    }
    
    protected String getText(Object object) {
        
        if(labelProvider == null) {
            return object.toString();
        }
        
        return labelProvider.getText(object);
    }
}
